import { Scene_Battle } from '../module/battle/Scene_Battle';
import { _decorator, AssetManager, assetManager, Color, Component, Label, Node, ProgressBar, tween, Tween, screen, view, Size, Button, game, sys, Canvas, director, find, View, BufferAsset, resources } from 'cc';
import { UIComponent } from '../../platform/ui/UIComponent';
import { bind } from '../../platform/ui/UIDecorator';
import { GameCtx } from '../GameCtx';
import { LogMgr } from '../../platform/log/LogMgr';
import { EnterGameProgress } from '../AppCfgs';
import { ResManager } from '../../platform/resources/ResMgr';
import { PlayerData } from '../data/player/PlayerData';
import { SceneMgr } from '../../platform/scene/SceneMgr';
import { SceneDefine, ViewDefine, ViewLayerDefine } from '../common/enums';
import { TbRoot } from '../../platform/excel_table/TbRoot';
import AudioMgr from '../../platform/audio/AudioMgr';
import { TimeMgr } from '../../platform/time/TimeMgr';
import UIMgr from '../../platform/ui/UIMgr';
import { scene_infos } from '../static_config';
import BaseView from '../../platform/ui/BaseView';




const { ccclass, property } = _decorator;

@ccclass('Loading')
export class Loading extends UIComponent {

    @bind(Label)
    loading_tip:Label;
    @bind(ProgressBar)
    loading_process:ProgressBar;
    @bind(Label)
    percent:Label;

    progressTween:Tween
    percentTween:Tween
    start() {

        //游戏上下文初始化
        GameCtx.ins.init()
        //日志初始化
        LogMgr.logOpen = GameCtx.ins.platformCfg.log.logOpen
        LogMgr.logLevel = GameCtx.ins.platformCfg.log.logLvel
        //启动游戏逻辑
        //分包策略：
        //1.主包：包含启动场景，启动场景加载优先级最高的分包：resources和script  【主包限制在4M内，这3个部分总体积要限制在40M内(微信规定的)】
        //2.按成长等级段分包：(可以细分到章节任务，地图等，后面的资源就可以在用到时加载)
        //3.按功能分包：（这样只加载开放的功能和即将开放的几个功能）
        //4.按活动分包：（只加载解锁的活动和正在进行中的活动）
        //5.分包可以放在游戏包体和远程CDN里，
        //CDN里可以放：配置表数据，较大的美术资源(背景图，时装，头像，特效，字体等)，icon（功能，货币，道具，ui等）
        this.gameStart()
    }


    async gameStart(){
        this.localEnvironmentInit();

        this.setLoadingProgress(EnterGameProgress.LocalEnvironmentOk.tips,EnterGameProgress.LocalEnvironmentOk.progress)
        //WX登录
        this.setLoadingProgress(EnterGameProgress.PlatformLogin.tips,EnterGameProgress.PlatformLogin.progress)
        //游戏服登录
        //TODO 检查登录状态{成功，封禁，关服等等}
        this.setLoadingProgress(EnterGameProgress.GameServerLogin.tips,EnterGameProgress.GameServerLogin.progress)

        let assetsCfg = GameCtx.ins.platformCfg.asset
        for(let key in assetsCfg){
            let cfg = assetsCfg[key]
            ResManager.inst.addBundleMeta(cfg.name,assetsCfg[key])
        }
        for(let key in assetsCfg){
            let cfg = assetsCfg[key]
            if(!cfg.remote){
                await ResManager.inst.loadBundle(cfg.name)
            }
        }

        //加载分包资源(配置表，当前已解锁功能对应的功能资源，当前已开放活动的活动资源)
        await this.loadSubPackage();

        //TODO 游戏服数据设置到本地
        PlayerData.ins.loadData()
        // gameData.playerUid.value = 10001+""

        this.setLoadingProgress(EnterGameProgress.AllDone.tips,EnterGameProgress.AllDone.progress)
        this.scheduleOnce(()=>{
            SceneMgr.ins.enterScene(SceneDefine.Scene_Battle,()=>{
                // UIMgr.ins.showUI(HomeView)
            })
        },0.5)
        this.netSetting()
    }
    netSetting() {

        // ApiDemo.wearEquip(1).then().error()
        // ApiDemo.wearEquipSync(1)
    }
    async loadSubPackage() {
        //加配置表
        const binaryMap = [".cfg"];
        const binaryDownloader = assetManager.downloader["_downloadArrayBuffer"];
        binaryMap.forEach((extName) => assetManager.downloader.register(extName, binaryDownloader));

        //加载所有配置表(横表和竖表)
        await TbRoot.ins.loadTbs("",true,".cfg",()=>{
            this.setLoadingTip("配置表加载失败！",false)
        })
        // let container = TbMgr.ins.getTbContainer(Tb_EquipContainer)
        // let cfg = container.getCfgById(1)
        // console.log("装备id："+cfg.id);
        this.setLoadingProgress(EnterGameProgress.TbDataLoadOk.tips,EnterGameProgress.TbDataLoadOk.progress)
        //加载通用资源
        
        //加载远程资源(开发环境直接加载，生成环境按条件加载)

        //加载预制件(UI,ui组件，场景组件等)
        //加载ui图标资源(通用的和具体功能/活动的)
        //TODO 资源加载完后进入
    }
    localEnvironmentInit() {
                //1.平台初始化（wx,抖音等）
        //TODO sys.Platform 获取当前运行平台  window["xx"] 从不同平台文档获得对应平台api的方法
        //TODO 确定平台后，初始化对应平台的SDK类，对提供的方法进行封装

        //2.屏幕适配？
        this.fitScreen()
        //3.TODO 渠道信息初始化（接入渠道才有）

        //4.TODO api 相关收集（cmdId和对应处理器，protobuf解析器等）
        //TODO 使用装饰器创建代理，解析方法，收集cmd，参数和返回值

        //5.添加全局按钮音效(为啥不用input来监听全局事件呢)
        let audioMgr = AudioMgr.ins
        this.addGlobalBtnSfx();

        //6.TODO 解析启动url上的参数，别人可以根据url来打开小游戏，url上的参数可以解析出来

        //7.处理安全区域（Safe Area）通常是为了适配不同设备的屏幕，特别是那些有刘海屏或圆角的设备（如 iPhone X 及以上型号）
        // this.updateSafeArea()

        //8.监听窗口变化
        // screen.on("window-resize",()=>{
        //     this.updateSafeArea()
        //     //TODO 抛出事件，让游戏内监听
        // })
        //9.初始化语言(国际化才用)

        //10.时间管理器初始化并启动一个全局循环，每格一秒发布一次事件 //TODO 什么时候取消循环呢
        TimeMgr.ins.startLoop(this.globalSecLoop,1)


        //11.UI管理器初始化
        UIMgr.init(director.getScene().getChildByName("UI_Canvas"),[
            ViewLayerDefine.Main,
            ViewLayerDefine.Pop,
            ViewLayerDefine.Tips,
            ViewLayerDefine.Marquee,
            ViewLayerDefine.Top
        ])
        // UIMgr.init(director.getScene().getChildByName("UI_Canvas"))
        UIMgr.ins.globalBeforeShowFun  = this.globalBeforeUiShow

        //场景管理器
        SceneMgr.ins.setBeforeEnterFun(()=>{
            //关闭所有ui
            //显示loading的ui
            // UIMgr.ins.showUI(ViewDefine.Loading)
        })
        SceneMgr.ins.setAfterEnterFun(()=>{
            //关闭loading的ui
            // UIMgr.ins.closeView(ViewDefine.Loading)
        })
        SceneMgr.ins.setSceneInfoFun((sceneName)=>{
            //根据sceneName获取场景
            return scene_infos[sceneName]
        })
    }

    public loadBinaryTest(url:string){
        assetManager.loadRemote(url,(e,data)=>{
            if(e){
                new Error(e.stack)
                return
            }
            console.error("加载成功：",data);
            let cfgBuffer = data.nativeAsset as ArrayBuffer
            let dv = new DataView(cfgBuffer)
            let read = dv.getUint32(0)
            console.log("读取到二进制配置："+read)
            return
        })
    }

    public globalBeforeUiShow(layerNode:Node,view:BaseView<any,any>,stack:BaseView<any,any>[]){
        let viewName = Object.getPrototypeOf(view).constructor.name
        let viewInfo = UIMgr.viewInfos[viewName]
        if(!viewInfo){
            LogMgr.err("找不到视图信息："+viewName)
            return
        }
        let layer = viewInfo.layer
        if(layer==ViewLayerDefine.Main){
            view.useAnimation = false
            //关闭其他主层的ui
            stack.forEach((v)=>{
                let otherViewName = Object.getPrototypeOf(v).constructor.name
                if(otherViewName!=viewName){
                    v.closeView()
                }
            })
        }
        
    }
    public globalSecLoop(){
        // GlobalEventMgr.ins.emit(GlobalEventTyp.SecUpdate)
    }

    updateSafeArea2(){
        // 获取安全区域
        const safeArea = sys.getSafeAreaRect();

 
        // 获取 Canvas 的设计分辨率和实际分辨率
        // const designResolution = canvas.getContentSize();
        // const visibleRect = view.getVisibleSize();

        // // 计算安全区域在设计分辨率中的位置和大小
        // const safeAreaX = safeArea.x * (designResolution.width / visibleRect.width);
        // const safeAreaY = safeArea.y * (designResolution.height / visibleRect.height);
        // const safeAreaWidth = safeArea.width * (designResolution.width / visibleRect.width);
        // const safeAreaHeight = safeArea.height * (designResolution.height / visibleRect.height);

        // // 调整节点位置和大小
        // this.node.setPosition(safeAreaX, safeAreaY);
        // this.node.setContentSize(safeAreaWidth, safeAreaHeight);
    }
    updateSafeArea() {
        GameCtx.ins.designSize = view.getDesignResolutionSize();
        GameCtx.ins.stageSize = new Size(game.canvas.width, game.canvas.height);
        // if (Global.inst.platformInst) {
        //     Global.inst.platformInst.getSystemInfo({
        //         success: (r) => {
        //             //正式
        //             let screenWidth: number = r.screenWidth;
        //             let screenHeight: number = r.screenHeight;
        //             let orientation = SDKManager.inst.getDeviceOrientation();
        //             Global.inst.safeArea = r['safeArea'];
        //             if (orientation == "landscape") {
        //                 //横屏要调整
        //                 Global.inst.safeArea.width = Math.floor((Global.inst.safeArea.bottom / Global.inst.safeArea.width) * Global.inst.safeArea.bottom);
        //                 Global.inst.safeArea.right = Global.inst.safeArea.width;
        //             }

        //             this.onReiseBySafeArea(screenWidth, screenHeight);
        //         },
        //         fail: () => {
        //             Global.inst.safeWidth = Global.inst.screenSize.width;
        //             Global.inst.safeHeight = Global.inst.screenSize.height;
        //             if (Global.inst.screenSize.width)
        //                 Global.inst.safeX = 0;
        //             Global.inst.safeY = 0;
        //         },
        //         complete: null
        //     })
        // } else {
        //     // if (Global.inst.isIOS() || Global.inst.isAndroid()) {
        //     //     SDKManager.inst.getSafeArea().then(data => {
        //     //         console.log("yomiko :" + "safeArea1:" + data);
        //     //         Global.inst.safeArea = { bottom: parseFloat(data[5]) - parseFloat(data[1]), height: parseFloat(data[5]) - parseFloat(data[0]) - parseFloat(data[1]), left: parseFloat(data[2]), right: parseFloat(data[4]) - parseFloat(data[3]), top: parseFloat(data[0]), width: parseFloat(data[4]) - parseFloat(data[3]) - parseFloat(data[2]) };
        //     //         console.log("yomiko :" + "safeArea4:" + JSON.stringify(Global.inst.safeArea));
        //     //         let screenWidth: number = parseFloat(data[4]);
        //     //         let screenHeight: number = parseFloat(data[5]);
        //     //         this.onReiseBySafeArea(screenWidth, screenHeight);
        //     //     });
        //     // } else {
        //     Global.inst.safeWidth = Global.inst.screenSize.width
        //     Global.inst.safeHeight = Global.inst.screenSize.height;
        //     // if (Global.inst.safeWidth / Global.inst.screenSize.height > Constant.SafeScale) {
        //     //     Global.inst.safeWidth = Global.inst.screenSize.height * Constant.SafeScale;
        //     // }
        //     Global.inst.safeX = 0;
        //     Global.inst.safeY = 0;
        //     // }
        // }
        // 安全区域测试
        // Global.inst.test();
        // if (Global.inst.safeWidth / Global.inst.screenSize.height > Constant.SafeScale) {
        //     Global.inst.safeWidth = Global.inst.screenSize.height * Constant.SafeScale;
        // }
        GameCtx.ins.safeX = 0;
        GameCtx.ins.safeY = 0;
    }
    addGlobalBtnSfx() {
        if (Button.prototype["touchBeganClone"]) return;
        Button.prototype["touchBeganClone"] = Button.prototype["_onTouchEnded"];
        Button.prototype["_onTouchEnded"] = function (event) {
            if (this.interactable && this.enabledInHierarchy) {
                // 播放自己的按钮音效
                // ......
                // AudioMgr.ins.playSFX("dianji");
            }
            this.touchBeganClone(event);
        }
    }
    fitScreen() {
        // let size = screen.windowSize;
        // let screenWidth: number = size.width / view.getScaleX();
        // let screenHeight: number = size.height / view.getScaleY();
        // GameCtx.ins.screenSize = new Size(screenWidth, screenHeight);
        // console.log('cc screen', GameCtx.ins.screenSize);
    }

    setLoadingTip(tip:string,success:boolean = true){
        if(success){
            this.loading_tip.color = new Color("#000000");
        }else{
            this.loading_tip.color = new Color("#FF0000");
        }
        this.loading_tip.string = tip
    }
    setLoadingProgress(tip:string,progress:number,success:boolean = true){
        if(success){
            this.loading_tip.color = new Color("#000000");
        }else{
            this.loading_tip.color = new Color("#FF0000");
        }
        this.loading_tip.string = tip
        if(this.progressTween){
            this.progressTween.stop()
        }
        if(this.percentTween){
            this.percentTween.stop()
        }
        this.progressTween = tween(this.loading_process).to(1.5,{progress:progress},{
            onUpdate:(bar,ratio)=>{
                this.percent.string = (this.loading_process.progress*100).toFixed(0)+"%"
            }
        }).start()
    }

}


